-- Apply access token 
-- Written by Kevin.XU
-- 2016/7/13

--[[
Request body:::
{
    "service_type":"SHOPPING",
    "user_identify":"dadf233dfadf1132124",
    "at_expire_secs":1800,
    "user_member_level":"1",
    "user_term_type":"MOBILE/Andriod",
    "user_term_ip":"112.11.1.10"
}
Response body:::
{
    "status":0,
    "status_desc":"",
    "token":"eyJleHBpcmVfdGltZSI6MTQ2OTE4OTMxMSwibWVtYmVyX2xldmVsIjoiMSIsImxvZ2luX2F1dGgiOiJqYWNrIiwidmFsaWRpdHkiOjMwLCJjbGllbnRfaXAiOiIxMTIuMTEuMS4xMCIsImNsaWVudF90eXBlIjoiaXBob25lIn0="
}
]]

ngx.req.read_body()

local resty_redis = require "resty.redis"
local resty_cjson = require "cjson"
local resty_md5 = require "resty.md5"
local resty_string = require "resty.string"
local limit_toolkit = require "ddtk.limit_tk"
local redis_config = require "ddtk.redis_config"
local syncr_config = require "ddtk.syncr_config"
local syncr = require "libsyncr" 

local max_idle_timeout = 300*1000
local pool_size = 20
local timeout = 1000

--read request body and make token value
local now=os.time()
--ngx.log(ngx.INFO, "now is ", now)
local json_request_body_data = ngx.req.get_body_data()
--ngx.log(ngx.INFO, "request is : ", json_request_body_data)
local request_body = resty_cjson.decode(json_request_body_data) 
local service_type = request_body.service_type
local validity = request_body.at_expire_secs
local expire_time = now + validity
request_body['rand'] = math.random(90000)
request_body['at_expire_time'] = expire_time
local token_value = resty_cjson.encode(request_body)
token_value = limit_toolkit.to_base64(token_value)

local tkey_hex = limit_toolkit.md5(token_value)
if not tkey_hex then
    ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)
    return
end

--get redis address
local redis_ip,redis_port = redis_config.select_master_redis_node(service_type)
if redis_ip == nil then
    ngx.log(ngx.ERR, "not found redis")
    ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)
    return
end
local red = resty_redis:new()
red:set_timeout(timeout)
local ok, err = red:connect(redis_ip, redis_port)
if not ok then
    ngx.log(ngx.ERR, "connect failed")
    ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)
    return
end
--save token value into redis
ok, err = red:setex(tkey_hex, validity, "1")
if not ok then
    red:set_keepalive(max_idle_timeout, pool_size)
    ngx.log(ngx.ERR, "set failed")
    ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)
    return
end
local command = "set " .. tkey_hex .. " 1 EX " .. validity
ok, err = syncr.sync_command(syncr_config.get_msgid(service_type),command)
--ngx.log(ngx.INFO, "sync result : ", ok ," , err : ", err)
if not ok then
    red:set_keepalive(max_idle_timeout, pool_size)
    ngx.log(ngx.ERR, "sync failed")
    ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)
    return
end

--keep connection alive
red:set_keepalive(max_idle_timeout, pool_size)

--make response
local resp={}
resp['status']=0
resp['status_desc']=''
resp['token']=token_value
--resp['tkey']=tkey_hex
local resp_json = resty_cjson.encode(resp) 


ngx.say(resp_json)

